package com.mzj.saas.mservice.lockManager.service;

import com.mzj.saas.commons.ApiData;
import com.mzj.saas.commons.DateUtils;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.StatusCode;
import com.mzj.saas.commons.enums.OSSUploadFileTypeEnum;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.config.oss.OssConfig;
import com.mzj.saas.mservice.lockManager.entity.LockUpgradeScale;
import com.mzj.saas.mservice.lockManager.entity.LockUpgradeTask;
import com.mzj.saas.mservice.lockManager.entity.LockVersion;
import com.mzj.saas.mservice.lockManager.repository.LockUpgradeScaleRepository;
import com.mzj.saas.mservice.lockManager.repository.LockUpgradeTaskRepository;
import com.mzj.saas.mservice.lockManager.repository.LockVersionRepository;
import com.mzj.saas.mservice.lockManager.vo.*;
import com.mzj.saas.mservice.oss.service.OSSService;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class LockUpgradeService {
    private static final Logger log = LoggerFactory.getLogger(LockUpgradeService.class);

    private static final String SCALE_COUNT = "SELECT COUNT(1) ";
    private static final String SCALE_COLUM = "SELECT s.id,s.lock_version_id AS versionId,v.name AS versionName,l.name as lockName,l.mac,\n" +
            "l.community_name AS communityName,l.build_name AS buildName,l.unit_name AS unitName,l.room_number AS roomNumber,s.create_time AS createTime,s.status";
    private static final String SCALE_FROM_MONITOR = " FROM `saas_lock_upgrade_scale` s\n" +
            "LEFT JOIN `saas_lock_version` v ON s.lock_version_id = v.id\n" +
            "LEFT JOIN `saas_smart_lock` l ON s.lock_id = l.id";
    private static final String SCALE_ORDER = " ORDER BY s.create_time DESC";
    private static final String VERSION_ORDER = " ORDER BY v.create_time DESC";
    private static final String TASK_ORDER = " ORDER BY t.create_time DESC";
    private static final String SQL_PAGE = " LIMIT ? OFFSET ?";

    @Autowired
    private RedisService redisService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private LockVersionRepository lockVersionRepository;
    @Autowired
    private OSSService ossService;
    @Autowired
    private OssConfig ossConfig;
    @Autowired
    private LockUpgradeTaskRepository lockUpgradeTaskRepository;
    @Autowired
    private LockUpgradeScaleRepository lockUpgradeScaleRepository;

    public ResultBean<ApiData<UpgradeScaleListVO>> upgradeScaleList(String accessToken, Integer type, String search,
                                                                    Long lockTaskId, String lockName, String mac, String communityId, Long buildId, Long unitId,
                                                                    Integer pageNumber, Integer pageSize) {
        ResultBean<ApiData<UpgradeScaleListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<UpgradeScaleListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1");

            if (type != null) {
                if (type == 1) {
                    where.append(" and s.status = 0");
                } else if (type == 2) {
                    where.append(" and (s.status = 1 or s.status = 2)");
                }
            }
            if (StringUtils.isNotBlank(search)) {
                where.append(" AND l.`community_name` LIKE ? OR l.`build_name` LIKE ? OR l.`unit_name` LIKE ? OR l.`room_number` LIKE ?");
                args.add("%" + search + "%");
                args.add("%" + search + "%");
                args.add("%" + search + "%");
                args.add("%" + search + "%");
            }
            if (lockTaskId != null) {
                where.append(" AND s.`lock_task_id` = ?");
                args.add(lockTaskId);
            }
            if (StringUtils.isNotBlank(lockName)) {
                where.append(" AND l.`name` LIKE ?");
                args.add("%" + lockName + "%");
            }
            if (StringUtils.isNotBlank(mac)) {
                where.append(" AND l.`mac` LIKE ?");
                args.add("%" + mac + "%");
            }
            if (StringUtils.isNotBlank(communityId)) {
                where.append(" AND l.`community_id` = ?");
                args.add(communityId);
            }
            if (buildId != null) {
                where.append(" AND l.`build_id` = ?");
                args.add(buildId);
            }
            if (unitId != null) {
                where.append(" AND l.`unit_id` = ?");
                args.add(unitId);
            }

            // 总记录数
            Long total = jdbcTemplate.queryForObject(SCALE_COUNT + SCALE_FROM_MONITOR + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }

            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<UpgradeScaleListVO> list = jdbcTemplate.query(SCALE_COLUM + SCALE_FROM_MONITOR + where + SCALE_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(UpgradeScaleListVO.class), args.toArray());

            for (UpgradeScaleListVO vo : list) {
                String createTime = vo.getCreateTime();
                vo.setCreateTime(DateUtils.format(createTime, DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
            }

            apiData.setData(list);
            apiData.setTotal(total);

            resultBean.setResultData(apiData);
        } catch (Exception e) {
            log.error("LockUpgradeService upgradeScaleList Exception = {}" + e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        resultBean.setResultData(apiData);
        return resultBean;
    }

    public ResultBean<ApiData<VersionListVO>> versionList(String accessToken, Integer pageNumber, Integer pageSize) {
        ResultBean<ApiData<VersionListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<VersionListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1 AND v.status = 1");

            // 总记录数
            Long total = jdbcTemplate.queryForObject("SELECT count(1) FROM `saas_lock_version` v LEFT JOIN `saas_smart_lock_brand` b ON v.brand_id = b.id\n" +
                    "LEFT JOIN saas_user u ON v.operator_id = u.id" + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }

            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<VersionListVO> list = jdbcTemplate.query("SELECT v.id,v.brand_id AS brandId,b.name AS brandName,v.name,v.upgrade_file AS upgradeFile,v.operator_id AS operatorId,u.name AS operatorName,v.create_time AS createTime            \n" +
                            "FROM `saas_lock_version` v LEFT JOIN `saas_smart_lock_brand` b ON  v.brand_id = b.id\n" +
                            "LEFT JOIN saas_user u ON v.operator_id = u.id" + where + VERSION_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(VersionListVO.class), args.toArray());

            for (VersionListVO vo : list) {
                vo.setCreateTime(DateUtils.format(vo.getCreateTime(), DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
            }

            apiData.setData(list);
            apiData.setTotal(total);

            resultBean.setResultData(apiData);
        } catch (Exception e) {
            log.error("LockUpgradeService versionList Exception = {}" + e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        resultBean.setResultData(apiData);
        return resultBean;
    }

    @Transactional
    public ResultBean<Object> deleteVersion(String accessToken, Long id) {
        try {
            if (id == null) {
                return ResultBean.failedResultOfParamWithMsg("id为空");
            }

            lockVersionRepository.updateStatus(id, 2);

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("LockUpgradeService deleteLockBrand Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> saveVersion(String accessToken, Long brandId, String name, MultipartFile file) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();

            if (brandId == null) {
                return ResultBean.failedResultOfParamWithMsg("品牌id为空");
            }
            if (StringUtils.isBlank(name)) {
                return ResultBean.failedResultOfParamWithMsg("版本名称为空");
            }
            if (file == null) {
                return ResultBean.failedResultOfParamWithMsg("文件为空");
            }

            // 上传文件
            ResultBean<Object> objectResultBean = ossService.putFile(ossConfig.getOssBucketName(), file, OSSUploadFileTypeEnum.VERSION.toString());
            String code = objectResultBean.getCode();
            String msg = objectResultBean.getMsg();
            if (!code.equals(StatusCode.SUCCESS_CODE_10000.getErrorCode())) {
                return ResultBean.failedResultWithCodeAndMsg(code, msg);
            } else {
                String fileKey = objectResultBean.getResultData().toString();
                String url = ossService.getOssFilePath(fileKey);

                LockVersion lockVersion = new LockVersion();
                lockVersion.setBrandId(brandId);
                lockVersion.setName(name);
                lockVersion.setUpgradeFile(url);
                lockVersion.setStatus(1);
                lockVersion.setOperatorId(userId);
                lockVersion.setCreateTime(new Date());
                lockVersionRepository.save(lockVersion);
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("LockUpgradeService saveVersion Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<ApiData<UpgradeTaskListVO>> upgradeTaskList(String accessToken, Integer pageNumber, Integer pageSize) {
        ResultBean<ApiData<UpgradeTaskListVO>> resultBean = new ResultBean<>();
        resultBean.setCode("10000");
        resultBean.setMsg("10000");
        ApiData<UpgradeTaskListVO> apiData = new ApiData<>();
        resultBean.setResultData(apiData);
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }

            StringBuilder where = new StringBuilder();
            List<Object> args = new ArrayList<>();
            where.append(" where 1 = 1");

            // 总记录数
            Long total = jdbcTemplate.queryForObject("SELECT count(1)\n" +
                    "FROM `saas_lock_upgrade_task` t \n" +
                    "LEFT JOIN `saas_smart_lock_brand` b ON  t.brand_id = b.id\n" +
                    "LEFT JOIN `saas_lock_version` v ON  t.lock_version_id = v.id\n" +
                    "LEFT JOIN saas_user u ON v.operator_id = u.id" + where, args.toArray(), Long.class);
            if (total == 0) {
                return resultBean;
            }

            args.add(pageSize);
            args.add(pageNumber * pageSize);
            List<UpgradeTaskListVO> list = jdbcTemplate.query("SELECT t.id,t.brand_id AS brandId,b.name AS brandName,\n" +
                            "t.lock_version_id AS lockVersionId,v.name AS lockVersion,t.number,t.operator_id AS operatorId,\n" +
                            "u.name AS operatorName,t.create_time AS createTime \n" +
                            "FROM `saas_lock_upgrade_task` t\n" +
                            "LEFT JOIN `saas_smart_lock_brand` b ON  t.brand_id = b.id\n" +
                            "LEFT JOIN `saas_lock_version` v ON  t.lock_version_id = v.id\n" +
                            "LEFT JOIN saas_user u ON v.operator_id = u.id" + where + TASK_ORDER + SQL_PAGE,
                    new BeanPropertyRowMapper<>(UpgradeTaskListVO.class), args.toArray());

            for (UpgradeTaskListVO vo : list) {
                vo.setCreateTime(DateUtils.format(vo.getCreateTime(), DateUtils.FORMAT_DATETIME_14, DateUtils.FORMAT_DATETIME_14));
            }

            apiData.setData(list);
            apiData.setTotal(total);

            resultBean.setResultData(apiData);
        } catch (Exception e) {
            log.error("LockUpgradeService upgradeTaskList Exception = {}" + e.getMessage(), e);
            resultBean.setCode("10001");
            resultBean.setMsg("10001");
        }
        resultBean.setResultData(apiData);
        return resultBean;
    }

    public ResultBean<List<LockVersionVO>> findBrandVersion(String accessToken, Long brandId) {
        try {
            if (brandId == null) {
                return ResultBean.failedResultOfParamWithMsg("品牌id为空");
            }

            List<LockVersionVO> list = jdbcTemplate.query("SELECT v.id AS versionId,v.name AS versionName FROM saas_lock_version v WHERE v.brand_id = ? AND v.status = 1 ",
                    new BeanPropertyRowMapper<>(LockVersionVO.class), brandId);

            return ResultBean.successfulResult(list);
        } catch (Exception e) {
            log.error("LockUpgradeService saveUpgradeTask Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    public ResultBean<Object> saveUpgradeTask(String accessToken, SaveUpgradeTaskVO vo) {
        try {
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            String userId = tokenRedisVo.getId();

            Long brandId = vo.getBrandId();
            Long lockVersionId = vo.getLockVersionId();
            List<Long> lockIds = vo.getLockIds();
            if (brandId == null) {
                return ResultBean.failedResultOfParamWithMsg("品牌id为空");
            }
            if (lockVersionId == null) {
                return ResultBean.failedResultOfParamWithMsg("版本id为空");
            }
            if (lockIds.isEmpty() || lockIds == null) {
                return ResultBean.failedResultOfParamWithMsg("设备id为空");
            }

            Date date = new Date();
            LockUpgradeTask task = new LockUpgradeTask();
            task.setBrandId(brandId);
            task.setLockVersionId(lockVersionId);
            task.setNumber(lockIds.size());
            task.setOperatorId(userId);
            task.setCreateTime(date);
            LockUpgradeTask save = lockUpgradeTaskRepository.save(task);

            //新增升级设备明细
            for (Long lockId : lockIds) {
                LockUpgradeScale scale = new LockUpgradeScale();
                scale.setLockVersionId(lockVersionId);
                scale.setLockTaskId(save.getId());
                scale.setLockId(lockId);
                scale.setStatus(0);
                scale.setCreateTime(date);
                lockUpgradeScaleRepository.save(scale);
            }

            return ResultBean.successfulResult(null);
        } catch (Exception e) {
            log.error("LockUpgradeService saveUpgradeTask Exception = {}" + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }


}
